/*
 * Copyright (C) 2010,2011  Paulo Cesar Pereira de Andrade.
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Authors:
 *	Paulo Cesar Pereira de Andrade
 */

/*
 * Prototypes
 */
#if PROTO
static void
vc_div_c_vc(vc_t *u, c_t v, vc_t *w, eint32_t m);

static void
vc_div_vc_c(vc_t *u, vc_t *v, c_t w, eint32_t m);

static void
vc_div_vc_vc(vc_t *u, vc_t *v, vc_t *w, eint32_t m);

#if HAVE_SIMD
static void
cp_div_c_cp(c_t *u, c_t v, c_t *w, eint32_t m);

static void
cp_div_cp_c(c_t *u, c_t *v, c_t w, eint32_t m);

static void
cp_div_cp_cp(c_t *u, c_t *v, c_t *w, eint32_t m);
#endif

static void
vs_div_s_vs(vs_t *u, s_t v, vs_t *w, eint32_t m);

static void
vs_div_vs_s(vs_t *u, vs_t *v, s_t w, eint32_t m);

static void
vs_div_vs_vs(vs_t *u, vs_t *v, vs_t *w, eint32_t m);

#if HAVE_SIMD
static void
sp_div_s_sp(s_t *u, s_t v, s_t *w, eint32_t m);

static void
sp_div_sp_s(s_t *u, s_t *v, s_t w, eint32_t m);

static void
sp_div_sp_sp(s_t *u, s_t *v, s_t *w, eint32_t m);
#endif

static void
vi_div_i_vi(vi_t *u, i_t v, vi_t *w, eint32_t m);

static void
vi_div_vi_i(vi_t *u, vi_t *v, i_t w, eint32_t m);

static void
vi_div_vi_vi(vi_t *u, vi_t *v, vi_t *w, eint32_t m);

#if HAVE_SIMD
static void
ip_div_i_ip(i_t *u, i_t v, i_t *w, eint32_t m);

static void
ip_div_ip_i(i_t *u, i_t *v, i_t w, eint32_t m);

static void
ip_div_ip_ip(i_t *u, i_t *v, i_t *w, eint32_t m);
#endif

static void
vl_div_l_vl(vl_t *u, l_t v, vl_t *w, eint32_t m);

static void
vl_div_vl_l(vl_t *u, vl_t *v, l_t w, eint32_t m);

static void
vl_div_vl_vl(vl_t *u, vl_t *v, vl_t *w, eint32_t m);

#if HAVE_SIMD
static void
lp_div_l_lp(l_t *u, l_t v, l_t *w, eint32_t m);

static void
lp_div_lp_l(l_t *u, l_t *v, l_t w, eint32_t m);

static void
lp_div_lp_lp(l_t *u, l_t *v, l_t *w, eint32_t m);
#endif

static void
vf_div_f_vf(vf_t *u, f_t v, vf_t *w, eint32_t m);

static void
vf_div_vf_f(vf_t *u, vf_t *v, f_t w, eint32_t m);

static void
vf_div_vf_vf(vf_t *u, vf_t *v, vf_t *w, eint32_t m);

#if HAVE_SIMD
static void
fp_div_f_fp(f_t *u, f_t v, f_t *w, eint32_t m);

static void
fp_div_fp_f(f_t *u, f_t *v, f_t w, eint32_t m);

static void
fp_div_fp_fp(f_t *u, f_t *v, f_t *w, eint32_t m);
#endif

static void
vd_div_d_vd(vd_t *u, d_t v, vd_t *w, eint32_t m);

static void
vd_div_vd_d(vd_t *u, vd_t *v, d_t w, eint32_t m);

static void
vd_div_vd_vd(vd_t *u, vd_t *v, vd_t *w, eint32_t m);

#if HAVE_SIMD
static void
dp_div_d_dp(d_t *u, d_t v, d_t *w, eint32_t m);

static void
dp_div_dp_d(d_t *u, d_t *v, d_t w, eint32_t m);

static void
dp_div_dp_dp(d_t *u, d_t *v, d_t *w, eint32_t m);
#endif

static void
vo_div_i_vo(vo_t *u, l_t v, vo_t *w, eint32_t m);

static void
vo_div_vo_i(vo_t *u, vo_t *v, l_t w, eint32_t m);

static void
vo_div_d_vo(vo_t *u, d_t v, vo_t *w, eint32_t m);

static void
vo_div_vo_d(vo_t *u, vo_t *v, d_t w, eint32_t m);

static void
vo_div_z_vo(vo_t *u, empz_t v, vo_t *w, eint32_t m);

static void
vo_div_vo_z(vo_t *u, vo_t *v, empz_t w, eint32_t m);

static void
vo_div_q_vo(vo_t *u, empq_t v, vo_t *w, eint32_t m);

static void
vo_div_vo_q(vo_t *u, vo_t *v, empq_t w, eint32_t m);

static void
vo_div_r_vo(vo_t *u, empr_t v, vo_t *w, eint32_t m);

static void
vo_div_vo_r(vo_t *u, vo_t *v, empr_t w, eint32_t m);

static void
vo_div_dd_vo(vo_t *u, ecdd_t v, vo_t *w, eint32_t m);

static void
vo_div_vo_dd(vo_t *u, vo_t *v, ecdd_t w, eint32_t m);

static void
vo_div_qq_vo(vo_t *u, ecqq_t v, vo_t *w, eint32_t m);

static void
vo_div_vo_qq(vo_t *u, vo_t *v, ecqq_t w, eint32_t m);

static void
vo_div_cc_vo(vo_t *u, empc_t v, vo_t *w, eint32_t m);

static void
vo_div_vo_cc(vo_t *u, vo_t *v, empc_t w, eint32_t m);

static void
vo_div_vo_vo(vo_t *u, vo_t *v, vo_t *w, eint32_t m);

static void
o_div_o_o(o_t *u, o_t *v, o_t *w);
#endif

/*
 * Implementation
 */
#if CODE
void
evector_int_div(eint_t a, evector_t *b, etype_t t)
{
    eint32_t	 l;
#if HAVE_SIMD
    eint32_t	 d;
#endif
    evector_t	*v;
    etype_t	 vt;
    v_enter();

    l = b->length;
    v_check(2);
    if (a > 2147483647 || a < -2147483647)
	vt = match(t_int64, t, 0, 0);
    else if (a > 32767 || a < -32767)
	vt = match(t_int32, t, 0, 0);
    else if (a > 127 || a < -127)
	vt = match(t_int16, t, 0, 0);
    else
	vt = match(t_int8, t, 0, 0);
    if (vt != t)
	b = coerce(b, t, vt);
    v = create(b, vt);
#if HAVE_SIMD
    switch (vt) {
	case t_int8:
	    if ((l >>= 4))
		vc_div_c_vc(v->v.obj, a, b->v.obj, l);
	    if ((d = v->length & 0xf))
		cp_div_c_cp((c_t *)v->v.obj + (l << 4),
			    a, (c_t *)b->v.obj + (l << 4), d);
	    break;
	case t_int16:
	    if ((l >>= 3))
		vs_div_s_vs(v->v.obj, a, b->v.obj, l);
	    if ((d = v->length & 0x7))
		sp_div_s_sp((s_t *)v->v.obj + (l << 3),
			    a, (s_t *)b->v.obj + (l << 3), d);
	    break;
	case t_int32:
	    if ((l >>= 2))
		vi_div_i_vi(v->v.obj, a, b->v.obj, l);
	    if ((d = v->length & 0x3))
		ip_div_i_ip((i_t *)v->v.obj + (l << 2),
			    a, (i_t *)b->v.obj + (l << 2), d);
	    break;
	case t_int64:
	    if ((l >>= 1))
		vl_div_l_vl(v->v.obj, a, b->v.obj, l);
	    if ((d = v->length & 0x1))
		lp_div_l_lp((l_t *)v->v.obj + (l << 1),
			    a, (l_t *)b->v.obj + (l << 1), d);
	    break;
	case t_float32:
	    if ((l >>= 2))
		vf_div_f_vf(v->v.obj, a, b->v.obj, l);
	    if ((d = v->length & 0x3))
		fp_div_f_fp((f_t *)v->v.obj + (l << 2),
			    a, (f_t *)b->v.obj + (l << 2), d);
	    break;
	case t_float64:
	    if ((l >>= 1))
		vd_div_d_vd(v->v.obj, a, b->v.obj, l);
	    if ((d = v->length & 0x1))
		dp_div_d_dp((d_t *)v->v.obj + (l << 1),
			    a, (d_t *)b->v.obj + (l << 1), d);
	    break;
	default:
	    vo_div_i_vo(v->v.obj, a, b->v.obj, l);
	    break;
    }
#else
    switch (vt) {
	case t_int8:
	    vc_div_c_vc(v->v.obj, a, b->v.obj, l);
	    break;
	case t_int16:
	    vs_div_s_vs(v->v.obj, a, b->v.obj, l);
	    break;
	case t_int32:
	    vi_div_i_vi(v->v.obj, a, b->v.obj, l);
	    break;
	case t_int64:
	    vl_div_l_vl(v->v.obj, a, b->v.obj, l);
	    break;
	case t_float32:
	    vf_div_f_vf(v->v.obj, a, b->v.obj, l);
	    break;
	case t_float64:
	    vd_div_d_vd(v->v.obj, a, b->v.obj, l);
	    break;
	default:
	    vo_div_i_vo(v->v.obj, a, b->v.obj, l);
	    break;
    }
#endif
    v_leave();
}

void
evector_div_int(evector_t *a, eint_t b, etype_t t)
{
    eint32_t	 l;
#if HAVE_SIMD
    eint32_t	 d;
#endif
    evector_t	*v;
    etype_t	 vt;
    v_enter();

    l = a->length;
    v_check(2);
    if (b > 2147483647 || b < -2147483647)
	vt = match(t_int64, t, 0, 0);
    else if (b > 32767 || b < -32767)
	vt = match(t_int32, t, 0, 0);
    else if (b > 127 || b < -127)
	vt = match(t_int16, t, 0, 0);
    else
	vt = match(t_int8, t, 0, 0);
    if (vt != t)
	a = coerce(a, t, vt);
    v = create(a, vt);
#if HAVE_SIMD
    switch (vt) {
	case t_int8:
	    if ((l >>= 4))
		vc_div_vc_c(v->v.obj, a->v.obj, b, l);
	    if ((d = v->length & 0xf))
		cp_div_cp_c((c_t *)v->v.obj + (l << 4),
			    (c_t *)a->v.obj + (l << 4), b, d);
	    break;
	case t_int16:
	    if ((l >>= 3))
		vs_div_vs_s(v->v.obj, a->v.obj, b, l);
	    if ((d = v->length & 0x7))
		sp_div_sp_s((s_t *)v->v.obj + (l << 3),
			    (s_t *)a->v.obj + (l << 3), b, d);
	    break;
	case t_int32:
	    if ((l >>= 2))
		vi_div_vi_i(v->v.obj, a->v.obj, b, l);
	    if ((d = v->length & 0x3))
		ip_div_ip_i((i_t *)v->v.obj + (l << 2),
			    (i_t *)a->v.obj + (l << 2), b, d);
	    break;
	case t_int64:
	    if ((l >>= 1))
		vl_div_vl_l(v->v.obj, a->v.obj, b, l);
	    if ((d = v->length & 0x1))
		lp_div_lp_l((l_t *)v->v.obj + (l << 1),
			    (l_t *)a->v.obj + (l << 1), b, d);
	    break;
	case t_float32:
	    if ((l >>= 2))
		vf_div_vf_f(v->v.obj, a->v.obj, b, l);
	    if ((d = v->length & 0x3))
		fp_div_fp_f((f_t *)v->v.obj + (l << 2),
			    (f_t *)a->v.obj + (l << 2), b, d);
	    break;
	case t_float64:
	    if ((l >>= 1))
		vd_div_vd_d(v->v.obj, a->v.obj, b, l);
	    if ((d = v->length & 0x1))
		dp_div_dp_d((d_t *)v->v.obj + (l << 1),
			    (d_t *)a->v.obj + (l << 1), b, d);
	    break;
	default:
	    vo_div_vo_i(v->v.obj, a->v.obj, b, l);
	    break;
    }
#else
    switch (vt) {
	case t_int8:
	    vc_div_vc_c(v->v.obj, a->v.obj, b, l);
	    break;
	case t_int16:
	    vs_div_vs_s(v->v.obj, a->v.obj, b, l);
	    break;
	case t_int32:
	    vi_div_vi_i(v->v.obj, a->v.obj, b, l);
	    break;
	case t_int64:
	    vl_div_vl_l(v->v.obj, a->v.obj, b, l);
	    break;
	case t_float32:
	    vf_div_vf_f(v->v.obj, a->v.obj, b, l);
	    break;
	case t_float64:
	    vd_div_vd_d(v->v.obj, a->v.obj, b, l);
	    break;
	default:
	    vo_div_vo_i(v->v.obj, a->v.obj, b, l);
	    break;
    }
#endif
    v_leave();
}

void
evector_float_div(efloat_t a, evector_t *b, etype_t t)
{
    eint32_t	 l;
    evector_t	*v;
    etype_t	 vt;
    v_enter();

    l = b->length;
    v_check(2);
    vt = match(t_float, t, 0, 0);
    if (vt != t)
	b = coerce(b, t, vt);
    v = create(b, vt);
    switch (vt) {
	case t_float64:
	    vd_div_d_vd(v->v.obj, a, b->v.obj, vd_length(l));
	    break;
	default:
	    vo_div_d_vo(v->v.obj, a, b->v.obj, l);
	    break;
    }
    v_leave();
}

void
evector_div_float(evector_t *a, efloat_t b, etype_t t)
{
    eint32_t	 l;
    evector_t	*v;
    etype_t	 vt;
    v_enter();

    l = a->length;
    v_check(2);
    vt = match(t_float, t, 0, 0);
    if (vt != t)
	a = coerce(a, t, vt);
    v = create(a, vt);
    switch (vt) {
	case t_float64:
	    vd_div_vd_d(v->v.obj, a->v.obj, b, vd_length(l));
	    break;
	default:
	    vo_div_vo_d(v->v.obj, a->v.obj, b, l);
	    break;
    }
    v_leave();
}

void
evector_mpz_div(empz_t a, evector_t *b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	b = coerce(b, t, t_void);
    v = create(b, t_void);
    vo_div_z_vo(v->v.obj, a, b->v.obj, v->length);
    v_leave();
}

void
evector_div_mpz(evector_t *a, empz_t b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	a = coerce(a, t, t_void);
    v = create(a, t_void);
    vo_div_vo_z(v->v.obj, a->v.obj, b, v->length);
    v_leave();
}

void
evector_mpq_div(empq_t a, evector_t *b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	b = coerce(b, t, t_void);
    v = create(b, t_void);
    vo_div_q_vo(v->v.obj, a, b->v.obj, v->length);
    v_leave();
}

void
evector_div_mpq(evector_t *a, empq_t b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	a = coerce(a, t, t_void);
    v = create(a, t_void);
    vo_div_vo_q(v->v.obj, a->v.obj, b, v->length);
    v_leave();
}

void
evector_mpr_div(empr_t a, evector_t *b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	b = coerce(b, t, t_void);
    v = create(b, t_void);
    vo_div_r_vo(v->v.obj, a, b->v.obj, v->length);
    v_leave();
}

void
evector_div_mpr(evector_t *a, empr_t b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	a = coerce(a, t, t_void);
    v = create(a, t_void);
    vo_div_vo_r(v->v.obj, a->v.obj, b, v->length);
    v_leave();
}

void
evector_cdd_div(ecdd_t a, evector_t *b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	b = coerce(b, t, t_void);
    v = create(b, t_void);
    vo_div_dd_vo(v->v.obj, a, b->v.obj, v->length);
    v_leave();
}

void
evector_div_cdd(evector_t *a, ecdd_t b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	a = coerce(a, t, t_void);
    v = create(a, t_void);
    vo_div_vo_dd(v->v.obj, a->v.obj, b, v->length);
    v_leave();
}

void
evector_cqq_div(ecqq_t a, evector_t *b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	b = coerce(b, t, t_void);
    v = create(b, t_void);
    vo_div_qq_vo(v->v.obj, a, b->v.obj, v->length);
    v_leave();
}

void
evector_div_cqq(evector_t *a, ecqq_t b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	a = coerce(a, t, t_void);
    v = create(a, t_void);
    vo_div_vo_qq(v->v.obj, a->v.obj, b, v->length);
    v_leave();
}

void
evector_mpc_div(empc_t a, evector_t *b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	b = coerce(b, t, t_void);
    v = create(b, t_void);
    vo_div_cc_vo(v->v.obj, a, b->v.obj, v->length);
    v_leave();
}

void
evector_div_mpc(evector_t *a, empc_t b, etype_t t)
{
    evector_t	*v;
    v_enter();

    v_check(2);
    if (t != t_void)
	a = coerce(a, t, t_void);
    v = create(a, t_void);
    vo_div_vo_cc(v->v.obj, a->v.obj, b, v->length);
    v_leave();
}

void
evector_div(evector_t *a, evector_t *b, etype_t at, etype_t bt)
{
    eint32_t	l;
#if HAVE_SIMD
    eint32_t	d;
#endif
    evop_t	o;
    v_enter();

    setup(&o, a, b, at, bt, 0, 0);
    l = o.r->length;
#if HAVE_SIMD
    switch (o.t) {
	case t_int8:
	    if ((l >>= 4))
		vc_div_vc_vc(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    if ((d = o.r->length & 0xf))
		cp_div_cp_cp((c_t *)o.r->v.obj + (l << 4),
			     (c_t *)o.a->v.obj + (l << 4),
			     (c_t *)o.b->v.obj + (l << 4), d);
	    break;
	case t_int16:
	    if ((l >>= 3))
		vs_div_vs_vs(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    if ((d = o.r->length & 0x7))
		sp_div_sp_sp((s_t *)o.r->v.obj + (l << 3),
			     (s_t *)o.a->v.obj + (l << 3),
			     (s_t *)o.b->v.obj + (l << 3), d);
	    break;
	case t_int32:
	    if ((l >>= 2))
		vi_div_vi_vi(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    if ((d = o.r->length & 0x3))
		ip_div_ip_ip((i_t *)o.r->v.obj + (l << 2),
			     (i_t *)o.a->v.obj + (l << 2),
			     (i_t *)o.b->v.obj + (l << 2), d);
	    break;
	case t_int64:
	    if ((l >>= 1))
		vl_div_vl_vl(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    if ((d = o.r->length & 0x1))
		lp_div_lp_lp((l_t *)o.r->v.obj + (l << 1),
			     (l_t *)o.a->v.obj + (l << 1),
			     (l_t *)o.b->v.obj + (l << 1), d);
	    break;
	case t_float32:
	    if ((l >>= 2))
		vf_div_vf_vf(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    if ((d = o.r->length & 0x3))
		fp_div_fp_fp((f_t *)o.r->v.obj + (l << 2),
			     (f_t *)o.a->v.obj + (l << 2),
			     (f_t *)o.b->v.obj + (l << 2), d);
	    break;
	case t_float64:
	    if ((l >>= 1))
		vd_div_vd_vd(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    if ((d = o.r->length & 0x1))
		dp_div_dp_dp((d_t *)o.r->v.obj + (l << 1),
			     (d_t *)o.a->v.obj + (l << 1),
			     (d_t *)o.b->v.obj + (l << 1), d);
	    break;
	default:
	    vo_div_vo_vo(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    break;
    }
#else
    switch (o.t) {
	case t_int8:
	    vc_div_vc_vc(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    break;
	case t_int16:
	    vs_div_vs_vs(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    break;
	case t_int32:
	    vi_div_vi_vi(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    break;
	case t_int64:
	    vl_div_vl_vl(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    break;
	case t_float32:
	    vf_div_vf_vf(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    break;
	case t_float64:
	    vd_div_vd_vd(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    break;
	default:
	    vo_div_vo_vo(o.r->v.obj, o.a->v.obj, o.b->v.obj, l);
	    break;
    }
#endif
    v_leave();
}

static void
vc_div_c_vc(vc_t *u, c_t v, vc_t *w, eint32_t m)
{
#if HAVE_SIMD
    vc_t	vc = { v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v };
#else
    register c_t vc = v;
#endif

    while (m--)
	*u++ = vc / *w++;
}

static void
vc_div_vc_c(vc_t *u, vc_t *v, c_t w, eint32_t m)
{
#if HAVE_SIMD
    vc_t	wc = { w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w };
#else
    register c_t wc = w;
#endif

    while (m--)
	*u++ = *v++ / wc;
}

static void
vc_div_vc_vc(vc_t *u, vc_t *v, vc_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}

#if HAVE_SIMD
static void
cp_div_c_cp(c_t *u, c_t v, c_t *w, eint32_t m)
{
    while (m--)
	*u++ = v / *w++;
}

static void
cp_div_cp_c(c_t *u, c_t *v, c_t w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / w;
}

static void
cp_div_cp_cp(c_t *u, c_t *v, c_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}
#endif

static void
vs_div_s_vs(vs_t *u, s_t v, vs_t *w, eint32_t m)
{
#if HAVE_SIMD
    vs_t	vs = { v, v, v, v, v, v, v, v };
#else
    register s_t vs = v;
#endif

    while (m--)
	*u++ = vs / *w++;
}

static void
vs_div_vs_s(vs_t *u, vs_t *v, s_t w, eint32_t m)
{
#if HAVE_SIMD
    vs_t	ws = { w, w, w, w, w, w, w, w };
#else
    register s_t ws = w;
#endif

    while (m--)
	*u++ = *v++ / ws;
}

static void
vs_div_vs_vs(vs_t *u, vs_t *v, vs_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}

#if HAVE_SIMD
static void
sp_div_s_sp(s_t *u, s_t v, s_t *w, eint32_t m)
{
    while (m--)
	*u++ = v / *w++;
}

static void
sp_div_sp_s(s_t *u, s_t *v, s_t w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / w;
}

static void
sp_div_sp_sp(s_t *u, s_t *v, s_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}
#endif

static void
vi_div_i_vi(vi_t *u, i_t v, vi_t *w, eint32_t m)
{
#if HAVE_SIMD
    vi_t	vi = { v, v, v, v };
#else
    register i_t vi = v;
#endif

    while (m--)
	*u++ = vi / *w++;
}

static void
vi_div_vi_i(vi_t *u, vi_t *v, i_t w, eint32_t m)
{
#if HAVE_SIMD
    vi_t	wi = { w, w, w, w };
#else
    register i_t wi = w;
#endif

    while (m--)
	*u++ = *v++ / wi;
}

static void
vi_div_vi_vi(vi_t *u, vi_t *v, vi_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}

#if HAVE_SIMD
static void
ip_div_i_ip(i_t *u, i_t v, i_t *w, eint32_t m)
{
    while (m--)
	*u++ = v / *w++;
}

static void
ip_div_ip_i(i_t *u, i_t *v, i_t w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / w;
}

static void
ip_div_ip_ip(i_t *u, i_t *v, i_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}
#endif

static void
vl_div_l_vl(vl_t *u, l_t v, vl_t *w, eint32_t m)
{
#if HAVE_SIMD
    vl_t	vl = { v, v };
#else
    register l_t vl = v;
#endif

    while (m--)
	*u++ = vl / *w++;
}

static void
vl_div_vl_l(vl_t *u, vl_t *v, l_t w, eint32_t m)
{
#if HAVE_SIMD
    vl_t	wl = { w, w };
#else
    register l_t wl = w;
#endif

    while (m--)
	*u++ = *v++ / wl;
}

static void
vl_div_vl_vl(vl_t *u, vl_t *v, vl_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}

#if HAVE_SIMD
static void
lp_div_l_lp(l_t *u, l_t v, l_t *w, eint32_t m)
{
    while (m--)
	*u++ = v / *w++;
}

static void
lp_div_lp_l(l_t *u, l_t *v, l_t w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / w;
}

static void
lp_div_lp_lp(l_t *u, l_t *v, l_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}
#endif

static void
vf_div_f_vf(vf_t *u, f_t v, vf_t *w, eint32_t m)
{
#if HAVE_SIMD
    vf_t	vf = { v, v, v, v };
#else
    register f_t vf = v;
#endif

    while (m--)
	*u++ = vf / *w++;
}

static void
vf_div_vf_f(vf_t *u, vf_t *v, f_t w, eint32_t m)
{
#if HAVE_SIMD
    vf_t	wf = { w, w, w, w };
#else
    register f_t wf = w;
#endif

    while (m--)
	*u++ = *v++ / wf;
}

static void
vf_div_vf_vf(vf_t *u, vf_t *v, vf_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}

#if HAVE_SIMD
static void
fp_div_f_fp(f_t *u, f_t v, f_t *w, eint32_t m)
{
    while (m--)
	*u++ = v / *w++;
}

static void
fp_div_fp_f(f_t *u, f_t *v, f_t w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / w;
}

static void
fp_div_fp_fp(f_t *u, f_t *v, f_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}
#endif

static void
vd_div_d_vd(vd_t *u, d_t v, vd_t *w, eint32_t m)
{
#if HAVE_SIMD
    vd_t	vd = { v, v };
#else
    register d_t vd = v;
#endif

    while (m--)
	*u++ = vd / *w++;
}

static void
vd_div_vd_d(vd_t *u, vd_t *v, d_t w, eint32_t m)
{
#if HAVE_SIMD
    vd_t	wd = { w, w };
#else
    register d_t wd = w;
#endif

    while (m--)
	*u++ = *v++ / wd;
}

static void
vd_div_vd_vd(vd_t *u, vd_t *v, vd_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}

#if HAVE_SIMD
static void
dp_div_d_dp(d_t *u, d_t v, d_t *w, eint32_t m)
{
    while (m--)
	*u++ = v / *w++;
}

static void
dp_div_dp_d(d_t *u, d_t *v, d_t w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / w;
}

static void
dp_div_dp_dp(d_t *u, d_t *v, d_t *w, eint32_t m)
{
    while (m--)
	*u++ = *v++ / *w++;
}
#endif

static void
vo_div_i_vo(vo_t *u, l_t v, vo_t *w, eint32_t m)
{
    for (; m; u++, w++, m--) {
	switch (eobject_type(*w)) {
	    case t_void:
		eraise_exception(except_floating_point_error);
		break;
	    case t_int:
		if (likely(v % get_i(w))) {
		    eq_div_i_i(thr_qr, v, get_i(w));
		    set_q(thr_qr);
		}
		else
		    set_i(v / get_i(w));
		break;
	    case t_float:
		set_d(v / get_d(w));
		break;
	    case t_mpz:
		switch (eq_div_i_z(thr_qr, v, get_z(w))) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case 0:
			set_q(thr_qr);
			break;
		    default:
			set_z(thr_zr);
			break;
		}
		break;
	    case t_mpq:
		switch (eq_div_i_q(thr_qr, v, get_q(w))) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case -1:
			set_z(thr_zr);
			break;
		    default:
			set_q(thr_qr);
			break;
		}
		break;
	    case t_mpr:
		er_div_i_r(thr_rr, v, get_r(w));
		set_r(thr_rr);
		break;
	    case t_cdd:
		set_dd(v / get_dd(w));
		break;
	    case t_cqq:
		eqq_div_i_qq(thr_qq, v, get_qq(w));
		set_qq(thr_qq);
		break;
	    case t_mpc:
		ecc_div_i_cc(thr_c, v, get_cc(w));
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
}

static void
vo_div_vo_i(vo_t *u, vo_t *v, l_t w, eint32_t m)
{
    for (; m; u++, v++, m--) {
	switch (eobject_type(*v)) {
	    case t_void:
		if (w == 0)
		    eraise_exception(except_floating_point_error);
		set_i(0);
		break;
	    case t_int:
		if (likely(get_i(v) % w)) {
		    eq_div_i_i(thr_qr, get_i(v), w);
		    set_q(thr_qr);
		}
		else
		    set_i(get_i(v) / w);
		break;
	    case t_float:
		set_d(get_d(v) / w);
		break;
	    case t_mpz:
		switch (eq_div_z_i(thr_qr, get_z(v), w)) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case -1:
			set_z(thr_zr);
			break;
		    default:
			set_q(thr_qr);
			break;
		}
		break;
	    case t_mpq:
		switch (eq_div_q_i(thr_qr, get_q(v), w)) {
		    case 0:
			set_q(thr_qr);
			break;
		    case -1:
			set_z(thr_zr);
			break;
		    default:
			set_i(empz_get_i(thr_zr));
			break;
		}
		break;
	    case t_mpr:
		er_div_r_i(thr_rr, get_r(v), w);
		set_r(thr_rr);
		break;
	    case t_cdd:
		set_dd(get_dd(v) / w);
		break;
	    case t_cqq:
		eqq_div_qq_i(thr_qq, get_qq(v), w);
		set_qq(thr_qq);
		break;
	    case t_mpc:
		ecc_div_cc_i(thr_c, get_cc(v), w);
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
}

static void
vo_div_d_vo(vo_t *u, d_t v, vo_t *w, eint32_t m)
{
    for (; m; u++, w++, m--) {
	switch (eobject_type(*w)) {
	    case t_void:
		set_d(v / 0.0);
		break;
	    case t_int:
		set_d(v / get_i(w));
		break;
	    case t_float:
		set_d(v / get_d(w));
		break;
	    case t_mpz:
		set_d(v / mpz_get_d(get_z(w)));
		break;
	    case t_mpq:
		set_d(v / mpq_get_d(get_q(w)));
		break;
	    case t_mpr:
		er_div_d_r(thr_rr, v, get_r(w));
		set_r(thr_rr);
		break;
	    case t_cdd:
		set_dd(v / get_dd(w));
		break;
	    case t_cqq:
		set_dd(edd_div_d_qq(v, get_qq(w)));
		break;
	    case t_mpc:
		ecc_div_d_cc(thr_c, v, get_cc(w));
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
}

static void
vo_div_vo_d(vo_t *u, vo_t *v, d_t w, eint32_t m)
{
    for (; m; u++, v++, m--) {
	switch (eobject_type(*v)) {
	    case t_void:
		set_d(0.0 / w);
		break;
	    case t_int:
		set_d(get_i(v) / w);
		break;
	    case t_float:
		set_d(get_d(v) / w);
		break;
	    case t_mpz:
		set_d(mpz_get_d(get_z(v)) / w);
		break;
	    case t_mpq:
		set_d(mpq_get_d(get_q(v)) / w);
		break;
	    case t_mpr:
		er_div_r_d(thr_rr, get_r(v), w);
		set_r(thr_rr);
		break;
	    case t_cdd:
		set_dd(get_dd(v) / w);
		break;
	    case t_cqq:
		set_dd(edd_div_qq_d(get_qq(v), w));
		break;
	    case t_mpc:
		ecc_div_cc_d(thr_c, get_cc(v), w);
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
}

static void
vo_div_z_vo(vo_t *u, empz_t v, vo_t *w, eint32_t m)
{
    ebool_t	b;

    if (unlikely((b = v == thr_zr))) {
	++thread_self->esp;
	eget_mpz(v, (thread_self->esp - thread_self->ess) - 1);
	v = thread_self->esp[-1].v.o;
    }
    for (; m; u++, w++, m--) {
	switch (eobject_type(*w)) {
	    case t_void:
		eraise_exception(except_floating_point_error);
		break;
	    case t_int:
		switch (eq_div_z_i(thr_qr, v, get_i(w))) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case -1:
			set_z(thr_zr);
			break;
		    default:
			set_q(thr_qr);
			break;
		}
		break;
	    case t_float:
		set_d(mpz_get_d(v) / get_d(w));
		break;
	    case t_mpz:
		switch (eq_div_z_z(thr_qr, v, get_z(w))) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case -1:
			set_z(thr_zr);
			break;
		    default:
			set_q(thr_qr);
			break;
		}
		break;
	    case t_mpq:
		switch (eq_div_z_q(thr_qr, v, get_q(w))) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case 0:
			set_q(thr_qr);
			break;
		    default:
			set_z(thr_zr);
			break;
		}
		break;
	    case t_mpr:
		er_div_z_r(thr_rr, v, get_r(w));
		set_r(thr_rr);
		break;
	    case t_cdd:
		set_dd(mpz_get_d(v) / get_dd(w));
		break;
	    case t_cqq:
		eqq_div_z_qq(thr_qq, v, get_qq(w));
		set_qq(thr_qq);
		break;
	    case t_mpc:
		ecc_div_z_cc(thr_c, v, get_cc(w));
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
    if (b)
	--thread_self->esp;
}

static void
vo_div_vo_z(vo_t *u, vo_t *v, empz_t w, eint32_t m)
{
    ebool_t	b;

    if (unlikely((b = w == thr_zr))) {
	++thread_self->esp;
	eget_mpz(w, (thread_self->esp - thread_self->ess) - 1);
	w = thread_self->esp[-1].v.o;
    }
    for (; m; u++, v++, m--) {
	switch (eobject_type(*v)) {
	    case t_void:
		set_i(0);
		break;
	    case t_int:
		switch (eq_div_i_z(thr_qr, get_i(v), w)) {
		    case 0:
			set_q(thr_qr);
			break;
		    case -1:
			set_z(thr_zr);
			break;
		    default:
			set_i(empz_get_i(thr_zr));
			break;
		}
		break;
	    case t_float:
		set_d(get_d(v) / mpz_get_d(w));
		break;
	    case t_mpz:
		switch (eq_div_z_z(thr_qr, get_z(v), w)) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case 0:
			set_q(thr_qr);
			break;
		    default:
			set_z(thr_zr);
			break;
		}
		break;
	    case t_mpq:
		switch (eq_div_q_z(thr_qr, get_q(v), w)) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case 0:
			set_q(thr_qr);
			break;
		    default:
			set_z(thr_zr);
			break;
		}
		break;
	    case t_mpr:
		er_div_r_z(thr_rr, get_r(v), w);
		set_r(thr_rr);
		break;
	    case t_cdd:
		set_dd(get_dd(v) / mpz_get_d(w));
		break;
	    case t_cqq:
		eqq_div_qq_z(thr_qq, get_qq(v), w);
		set_qq(thr_qq);
		break;
	    case t_mpc:
		ecc_div_cc_z(thr_c, get_cc(v), w);
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
    if (b)
	--thread_self->esp;
}

static void
vo_div_q_vo(vo_t *u, empq_t v, vo_t *w, eint32_t m)
{
    ebool_t	b;

    if (unlikely((b = v == thr_qr))) {
	++thread_self->esp;
	eget_mpq(v, (thread_self->esp - thread_self->ess) - 1);
	v = thread_self->esp[-1].v.o;
    }
    for (; m; u++, w++, m--) {
	switch (eobject_type(*w)) {
	    case t_void:
		eraise_exception(except_floating_point_error);
		break;
	    case t_int:
		switch (eq_div_q_i(thr_qr, v, get_i(w))) {
		    case 0:
			set_q(thr_qr);
			break;
		    case -1:
			set_z(thr_zr);
			break;
		    default:
			set_i(empz_get_i(thr_zr));
			break;
		}
		break;
	    case t_float:
		set_d(mpq_get_d(v) / get_d(w));
		break;
	    case t_mpz:
		switch (eq_div_q_z(thr_qr, v, get_z(w))) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case 0:
			set_q(thr_qr);
			break;
		    default:
			set_z(thr_zr);
			break;
		}
		break;
	    case t_mpq:
		switch (eq_div_q_q(thr_qr, v, get_q(w))) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case 0:
			set_q(thr_qr);
			break;
		    default:
			set_z(thr_zr);
			break;
		}
		break;
	    case t_mpr:
		er_div_q_r(thr_rr, v, get_r(w));
		set_r(thr_rr);
		break;
	    case t_cdd:
		set_dd(mpq_get_d(v) / get_dd(w));
		break;
	    case t_cqq:
		eqq_div_q_qq(thr_qq, v, get_qq(w));
		set_qq(thr_qq);
		break;
	    case t_mpc:
		ecc_div_q_cc(thr_c, v, get_cc(w));
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
    if (b)
	--thread_self->esp;
}

static void
vo_div_vo_q(vo_t *u, vo_t *v, empq_t w, eint32_t m)
{
    ebool_t	b;

    if (unlikely((b = w == thr_qr))) {
	++thread_self->esp;
	eget_mpq(w, (thread_self->esp - thread_self->ess) - 1);
	w = thread_self->esp[-1].v.o;
    }
    for (; m; u++, v++, m--) {
	switch (eobject_type(*v)) {
	    case t_void:
		set_i(0);
		break;
	    case t_int:
		switch (eq_div_i_q(thr_qr, get_i(v), w)) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case -1:
			set_z(thr_zr);
			break;
		    default:
			set_q(thr_qr);
			break;
		}
		break;
	    case t_float:
		set_d(get_d(v) / mpq_get_d(w));
		break;
	    case t_mpz:
		switch (eq_div_z_q(thr_qr, get_z(v), w)) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case 0:
			set_q(thr_qr);
			break;
		    default:
			set_z(thr_zr);
			break;
		}
		break;
	    case t_mpq:
		switch (eq_div_q_q(thr_qr, get_q(v), w)) {
		    case 1:
			set_i(empz_get_i(thr_zr));
			break;
		    case 0:
			set_q(thr_qr);
			break;
		    default:
			set_z(thr_zr);
			break;
		}
		break;
	    case t_mpr:
		er_div_r_q(thr_rr, get_r(v), w);
		set_r(thr_rr);
		break;
	    case t_cdd:
		set_dd(get_dd(v) / mpq_get_d(w));
		break;
	    case t_cqq:
		eqq_div_qq_q(thr_qq, get_qq(v), w);
		set_qq(thr_qq);
		break;
	    case t_mpc:
		ecc_div_cc_q(thr_c, get_cc(v), w);
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
    if (b)
	--thread_self->esp;
}

static void
vo_div_r_vo(vo_t *u, empr_t v, vo_t *w, eint32_t m)
{
    ebool_t	b;

    if (unlikely((b = v == thr_rr))) {
	++thread_self->esp;
	eget_mpr(v, (thread_self->esp - thread_self->ess) - 1);
	v = thread_self->esp[-1].v.o;
    }
    for (; m; u++, w++, m--) {
	switch (eobject_type(*w)) {
	    case t_void:
		er_div_r_i(thr_rr, v, 0);
		set_r(thr_rr);
		break;
	    case t_int:
		er_div_r_i(thr_rr, v, get_i(w));
		set_r(thr_rr);
		break;
	    case t_float:
		er_div_r_d(thr_rr, v, get_d(w));
		set_r(thr_rr);
		break;
	    case t_mpz:
		er_div_r_z(thr_rr, v, get_z(w));
		set_r(thr_rr);
		break;
	    case t_mpq:
		er_div_r_q(thr_rr, v, get_q(w));
		set_r(thr_rr);
		break;
	    case t_mpr:
		er_div_r_r(thr_rr, v, get_r(w));
		set_r(thr_rr);
		break;
	    case t_cdd:
		ecc_div_r_dd(thr_c, v, get_dd(w));
		set_cc(thr_c);
		break;
	    case t_cqq:
		ecc_div_r_qq(thr_c, v, get_qq(w));
		set_cc(thr_c);
		break;
	    case t_mpc:
		ecc_div_r_cc(thr_c, v, get_cc(w));
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
    if (b)
	--thread_self->esp;
}

static void
vo_div_vo_r(vo_t *u, vo_t *v, empr_t w, eint32_t m)
{
    ebool_t	b;

    if (unlikely((b = w == thr_rr))) {
	++thread_self->esp;
	eget_mpr(w, (thread_self->esp - thread_self->ess) - 1);
	w = thread_self->esp[-1].v.o;
    }
    for (; m; u++, v++, m--) {
	switch (eobject_type(*v)) {
	    case t_void:
		er_div_i_r(thr_rr, 0, w);
		set_r(thr_rr);
		break;
	    case t_int:
		er_div_i_r(thr_rr, get_i(v), w);
		set_r(thr_rr);
		break;
	    case t_float:
		er_div_d_r(thr_rr, get_d(v), w);
		set_r(thr_rr);
		break;
	    case t_mpz:
		er_div_z_r(thr_rr, get_z(v), w);
		set_r(thr_rr);
		break;
	    case t_mpq:
		er_div_q_r(thr_rr, get_q(v), w);
		set_r(thr_rr);
		break;
	    case t_mpr:
		er_div_r_r(thr_rr, get_r(v), w);
		set_r(thr_rr);
		break;
	    case t_cdd:
		ecc_div_dd_r(thr_c, get_dd(v), w);
		set_cc(thr_c);
		break;
	    case t_cqq:
		ecc_div_qq_r(thr_c, get_qq(v), w);
		set_cc(thr_c);
		break;
	    case t_mpc:
		ecc_div_cc_r(thr_c, get_cc(v), w);
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
    if (b)
	--thread_self->esp;
}

static void
vo_div_dd_vo(vo_t *u, ecdd_t v, vo_t *w, eint32_t m)
{
    for (; m; u++, w++, m--) {
	switch (eobject_type(*w)) {
	    case t_void:
		set_dd(v / 0.0);
		break;
	    case t_int:
		set_dd(v / get_i(w));
		break;
	    case t_float:
		set_dd(v / get_d(w));
		break;
	    case t_mpz:
		set_dd(v / mpz_get_d(get_z(w)));
		break;
	    case t_mpq:
		set_dd(v / mpq_get_d(get_q(w)));
		break;
	    case t_mpr:
		ecc_div_dd_r(thr_c, v, get_r(w));
		set_cc(thr_c);
		break;
	    case t_cdd:
		set_dd(v / get_dd(w));
		break;
	    case t_cqq:
		set_dd(edd_div_dd_qq(v, get_qq(w)));
		break;
	    case t_mpc:
		ecc_div_dd_cc(thr_c, v, get_cc(w));
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
}

static void
vo_div_vo_dd(vo_t *u, vo_t *v, ecdd_t w, eint32_t m)
{
    for (; m; u++, v++, m--) {
	switch (eobject_type(*v)) {
	    case t_void:
		set_dd(0.0 / w);
		break;
	    case t_int:
		set_dd(get_i(v) / w);
		break;
	    case t_float:
		set_dd(get_d(v) / w);
		break;
	    case t_mpz:
		set_dd(mpz_get_d(get_z(v)) / w);
		break;
	    case t_mpq:
		set_dd(mpq_get_d(get_q(v)) / w);
		break;
	    case t_mpr:
		ecc_div_r_dd(thr_c, get_r(v), w);
		set_cc(thr_c);
		break;
	    case t_cdd:
		set_dd(get_dd(v) / w);
		break;
	    case t_cqq:
		set_dd(edd_div_qq_dd(get_qq(v), w));
		break;
	    case t_mpc:
		ecc_div_cc_dd(thr_c, get_cc(v), w);
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
}

static void
vo_div_qq_vo(vo_t *u, ecqq_t v, vo_t *w, eint32_t m)
{
    ebool_t	b;

    if (unlikely((b = v == thr_qq))) {
	++thread_self->esp;
	eget_cqq(v, (thread_self->esp - thread_self->ess) - 1);
	v = thread_self->esp[-1].v.o;
    }
    for (; m; u++, w++, m--) {
	switch (eobject_type(*w)) {
	    case t_void:
		eraise_exception(except_floating_point_error);
		break;
	    case t_int:
		eqq_div_qq_i(thr_qq, v, get_i(w));
		set_qq(thr_qq);
		break;
	    case t_float:
		set_dd(edd_div_qq_d(v, get_d(w)));
		break;
	    case t_mpz:
		eqq_div_qq_z(thr_qq, v, get_z(w));
		set_qq(thr_qq);
		break;
	    case t_mpq:
		eqq_div_qq_q(thr_qq, v, get_q(w));
		set_qq(thr_qq);
		break;
	    case t_mpr:
		ecc_div_qq_r(thr_c, v, get_r(w));
		set_cc(thr_c);
		break;
	    case t_cdd:
		set_dd(edd_div_qq_dd(v, get_dd(w)));
		break;
	    case t_cqq:
		eqq_div_qq_qq(thr_qq, v, get_qq(w));
		set_qq(thr_qq);
		break;
	    case t_mpc:
		ecc_div_qq_cc(thr_c, v, get_cc(w));
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
    if (b)
	--thread_self->esp;
}

static void
vo_div_vo_qq(vo_t *u, vo_t *v, ecqq_t w, eint32_t m)
{
    ebool_t	b;

    if (unlikely((b = w == thr_qq))) {
	++thread_self->esp;
	eget_cqq(w, (thread_self->esp - thread_self->ess) - 1);
	w = thread_self->esp[-1].v.o;
    }
    for (; m; u++, v++, m--) {
	switch (eobject_type(*v)) {
	    case t_void:
		set_i(0);
		break;
	    case t_int:
		eqq_div_i_qq(thr_qq, get_i(v), w);
		set_qq(thr_qq);
		break;
	    case t_float:
		set_dd(edd_div_d_qq(get_d(v), w));
		break;
	    case t_mpz:
		eqq_div_z_qq(thr_qq, get_z(v), w);
		set_qq(thr_qq);
		break;
	    case t_mpq:
		eqq_div_q_qq(thr_qq, get_q(v), w);
		set_qq(thr_qq);
		break;
	    case t_mpr:
		ecc_div_r_qq(thr_c, get_r(v), w);
		set_cc(thr_c);
		break;
	    case t_cdd:
		set_dd(edd_div_dd_qq(get_dd(v), w));
		break;
	    case t_cqq:
		eqq_div_qq_qq(thr_qq, get_qq(v), w);
		set_qq(thr_qq);
		break;
	    case t_mpc:
		ecc_div_cc_qq(thr_c, get_cc(v), w);
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
    if (b)
	--thread_self->esp;
}

static void
vo_div_cc_vo(vo_t *u, empc_t v, vo_t *w, eint32_t m)
{
    ebool_t	b;

    if (unlikely((b = v == thr_c))) {
	++thread_self->esp;
	eget_mpc(v, (thread_self->esp - thread_self->ess) - 1);
	v = thread_self->esp[-1].v.o;
    }
    for (; m; u++, w++, m--) {
	switch (eobject_type(*w)) {
	    case t_void:
		ecc_div_cc_i(thr_c, v, 0);
		set_cc(thr_c);
		break;
	    case t_int:
		ecc_div_cc_i(thr_c, v, get_i(w));
		set_cc(thr_c);
		break;
	    case t_float:
		ecc_div_cc_d(thr_c, v, get_d(w));
		set_cc(thr_c);
		break;
	    case t_mpz:
		ecc_div_cc_z(thr_c, v, get_z(w));
		set_cc(thr_c);
		break;
	    case t_mpq:
		ecc_div_cc_q(thr_c, v, get_q(w));
		set_cc(thr_c);
		break;
	    case t_mpr:
		ecc_div_cc_r(thr_c, v, get_r(w));
		set_cc(thr_c);
		break;
	    case t_cdd:
		ecc_div_cc_dd(thr_c, v, get_dd(w));
		set_cc(thr_c);
		break;
	    case t_cqq:
		ecc_div_cc_qq(thr_c, v, get_qq(w));
		set_cc(thr_c);
		break;
	    case t_mpc:
		ecc_div_cc_cc(thr_c, v, get_cc(w));
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
    if (b)
	--thread_self->esp;
}

static void
vo_div_vo_cc(vo_t *u, vo_t *v, empc_t w, eint32_t m)
{
    ebool_t	b;

    if (unlikely((b = w == thr_c))) {
	++thread_self->esp;
	eget_mpc(w, (thread_self->esp - thread_self->ess) - 1);
	w = thread_self->esp[-1].v.o;
    }
    for (; m; u++, v++, m--) {
	switch (eobject_type(*v)) {
	    case t_void:
		ecc_div_i_cc(thr_c, 0, w);
		set_cc(thr_c);
		break;
	    case t_int:
		ecc_div_i_cc(thr_c, get_i(v), w);
		set_cc(thr_c);
		break;
	    case t_float:
		ecc_div_d_cc(thr_c, get_d(v), w);
		set_cc(thr_c);
		break;
	    case t_mpz:
		ecc_div_z_cc(thr_c, get_z(v), w);
		set_cc(thr_c);
		break;
	    case t_mpq:
		ecc_div_q_cc(thr_c, get_q(v), w);
		set_cc(thr_c);
		break;
	    case t_mpr:
		ecc_div_r_cc(thr_c, get_r(v), w);
		set_cc(thr_c);
		break;
	    case t_cdd:
		ecc_div_dd_cc(thr_c, get_dd(v), w);
		set_cc(thr_c);
		break;
	    case t_cqq:
		ecc_div_qq_cc(thr_c, get_qq(v), w);
		set_cc(thr_c);
		break;
	    case t_mpc:
		ecc_div_cc_cc(thr_c, get_cc(v), w);
		set_cc(thr_c);
		break;
	    default:
		eraise_exception(except_not_a_number);
	}
    }
    if (b)
	--thread_self->esp;
}

static void
vo_div_vo_vo(vo_t *u, vo_t *v, vo_t *w, eint32_t m)
{
    for (; m; m--, u++, v++, w++)
	o_div_o_o(u, v, w);
}

static void
o_div_o_o(o_t *u, o_t *v, o_t *w)
{
    switch (eobject_type(*v)) {
	case t_void:
	    switch (eobject_type(*w)) {
		case t_void:
		    eraise_exception(except_floating_point_error);
		case t_int:
		    set_i(0 / get_i(w));
		    break;
		case t_mpz:	case t_mpq:
		case t_cqq:
		    set_i(0);
		    break;
		case t_float:
		    set_d(0.0 / get_d(w));
		    break;
		case t_mpr:
		    er_div_i_r(thr_rr, 0, get_r(w));
		    set_r(thr_rr);
		    break;
		case t_cdd:
		    set_dd(0.0 / get_dd(w));
		    break;
		case t_mpc:
		    ecc_div_i_cc(thr_c, 0, get_cc(w));
		    set_cc(thr_c);
		    break;
		default:
		    eraise_exception(except_not_a_number);
	    }
	    break;
	case t_int:
	    switch (eobject_type(*w)) {
		case t_void:
		    eraise_exception(except_floating_point_error);
		case t_int:
		    if (likely(get_i(v) % get_i(w))) {
			eq_div_i_i(thr_qr, get_i(v), get_i(w));
			set_q(thr_qr);
		    }
		    else
			set_i(get_i(v) / get_i(w));
		    break;
		case t_float:
		    set_d(get_i(v) / get_d(w));
		    break;
		case t_mpz:
		    switch (eq_div_i_z(thr_qr, get_i(v), get_z(w))) {
			case 1:
			    set_i(empz_get_i(thr_zr));
			    break;
			case 0:
			    set_q(thr_qr);
			    break;
			default:
			    set_z(thr_zr);
			    break;
		    }
		    break;
		case t_mpq:
		    switch (eq_div_i_q(thr_qr, get_i(v), get_q(w))) {
			case 1:
			    set_i(empz_get_i(thr_zr));
			    break;
			case -1:
			    set_z(thr_zr);
			    break;
			default:
			    set_q(thr_qr);
			    break;
		    }
		    break;
		case t_mpr:
		    er_div_i_r(thr_rr, get_i(v), get_r(w));
		    set_r(thr_rr);
		    break;
		case t_cdd:
		    set_dd(get_i(v) / get_dd(w));
		    break;
		case t_cqq:
		    eqq_div_i_qq(thr_qq, get_i(v), get_qq(w));
		    set_qq(thr_qq);
		    break;
		case t_mpc:
		    ecc_div_i_cc(thr_c, get_i(v), get_cc(w));
		    set_cc(thr_c);
		    break;
		default:
		    eraise_exception(except_not_a_number);
	    }
	    break;
	case t_float:
	    switch (eobject_type(*w)) {
		case t_void:
		    set_d(get_d(v) / 0.0);
		    break;
		case t_int:
		    set_d(get_d(v) / get_i(w));
		    break;
		case t_float:
		    set_d(get_d(v) / get_d(w));
		    break;
		case t_mpz:
		    set_d(get_d(v) / mpz_get_d(get_z(w)));
		    break;
		case t_mpq:
		    set_d(get_d(v) / mpq_get_d(get_q(w)));
		    break;
		case t_mpr:
		    er_div_d_r(thr_rr, get_d(v), get_r(w));
		    set_r(thr_rr);
		    break;
		case t_cdd:
		    set_dd(get_d(v) / get_dd(w));
		    break;
		case t_cqq:
		    set_dd(edd_div_d_qq(get_d(v), get_qq(w)));
		    break;
		case t_mpc:
		    ecc_div_d_cc(thr_c, get_d(v), get_cc(w));
		    set_cc(thr_c);
		    break;
		default:
		    eraise_exception(except_not_a_number);
	    }
	    break;
	case t_mpz:
	    switch (eobject_type(*w)) {
		case t_void:
		    eraise_exception(except_floating_point_error);
		case t_int:
		    switch (eq_div_z_i(thr_qr, get_z(v), get_i(w))) {
			case 1:
			    set_i(empz_get_i(thr_zr));
			    break;
			case -1:
			    set_z(thr_zr);
			    break;
			default:
			    set_q(thr_qr);
			    break;
		    }
		    break;
		case t_float:
		    set_d(mpz_get_d(get_z(v)) / get_d(w));
		    break;
		case t_mpz:
		    switch (eq_div_z_z(thr_qr, get_z(v), get_z(w))) {
			case 1:
			    set_i(empz_get_i(thr_zr));
			    break;
			case -1:
			    set_z(thr_zr);
			    break;
			default:
			    set_q(thr_qr);
			    break;
		    }
		    break;
		case t_mpq:
		    switch (eq_div_z_q(thr_qr, get_z(v), get_q(w))) {
			case 1:
			    set_i(empz_get_i(thr_zr));
			    break;
			case 0:
			    set_q(thr_qr);
			    break;
			default:
			    set_z(thr_zr);
			    break;
		    }
		    break;
		case t_mpr:
		    er_div_z_r(thr_rr, get_z(v), get_r(w));
		    set_r(thr_rr);
		    break;
		case t_cdd:
		    set_dd(mpz_get_d(get_z(v)) / get_dd(w));
		    break;
		case t_cqq:
		    eqq_div_z_qq(thr_qq, get_z(v), get_qq(w));
		    set_qq(thr_qq);
		    break;
		case t_mpc:
		    ecc_div_z_cc(thr_c, get_z(v), get_cc(w));
		    set_cc(thr_c);
		    break;
		default:
		    eraise_exception(except_not_a_number);
	    }
	    break;
	case t_mpq:
	    switch (eobject_type(*w)) {
		case t_void:
		    eraise_exception(except_floating_point_error);
		case t_int:
		    switch (eq_div_q_i(thr_qr, get_q(v), get_i(w))) {
			case 0:
			    set_q(thr_qr);
			    break;
			case -1:
			    set_z(thr_zr);
			    break;
			default:
			    set_i(empz_get_i(thr_zr));
			    break;
		    }
		    break;
		case t_float:
		    set_d(mpq_get_d(get_q(v)) / get_d(w));
		    break;
		case t_mpz:
		    switch (eq_div_q_z(thr_qr, get_q(v), get_z(w))) {
			case 1:
			    set_i(empz_get_i(thr_zr));
			    break;
			case 0:
			    set_q(thr_qr);
			    break;
			default:
			    set_z(thr_zr);
			    break;
		    }
		    break;
		case t_mpq:
		    switch (eq_div_q_q(thr_qr, get_q(v), get_q(w))) {
			case 1:
			    set_i(empz_get_i(thr_zr));
			    break;
			case 0:
			    set_q(thr_qr);
			    break;
			default:
			    set_z(thr_zr);
			    break;
		    }
		    break;
		case t_mpr:
		    er_div_q_r(thr_rr, get_q(v), get_r(w));
		    set_r(thr_rr);
		    break;
		case t_cdd:
		    set_dd(mpq_get_d(get_q(v)) / get_dd(w));
		    break;
		case t_cqq:
		    eqq_div_q_qq(thr_qq, get_q(v), get_qq(w));
		    set_qq(thr_qq);
		    break;
		case t_mpc:
		    ecc_div_q_cc(thr_c, get_q(v), get_cc(w));
		    set_cc(thr_c);
		    break;
		default:
		    eraise_exception(except_not_a_number);
	    }
	    break;
	case t_mpr:
	    switch (eobject_type(*w)) {
		case t_void:
		    er_div_r_i(thr_rr, get_r(v), 0);
		    set_r(thr_rr);
		    break;
		case t_int:
		    er_div_r_i(thr_rr, get_r(v), get_i(w));
		    set_r(thr_rr);
		    break;
		case t_float:
		    er_div_r_d(thr_rr, get_r(v), get_d(w));
		    set_r(thr_rr);
		    break;
		case t_mpz:
		    er_div_r_z(thr_rr, get_r(v), get_z(w));
		    set_r(thr_rr);
		    break;
		case t_mpq:
		    er_div_r_q(thr_rr, get_r(v), get_q(w));
		    set_r(thr_rr);
		    break;
		case t_mpr:
		    er_div_r_r(thr_rr, get_r(v), get_r(w));
		    set_r(thr_rr);
		    break;
		case t_cdd:
		    ecc_div_r_dd(thr_c, get_r(v), get_dd(w));
		    set_cc(thr_c);
		    break;
		case t_cqq:
		    ecc_div_r_qq(thr_c, get_r(v), get_qq(w));
		    set_cc(thr_c);
		    break;
		case t_mpc:
		    ecc_div_r_cc(thr_c, get_r(v), get_cc(w));
		    set_cc(thr_c);
		    break;
		default:
		    eraise_exception(except_not_a_number);
	    }
	    break;
	case t_cdd:
	    switch (eobject_type(*w)) {
		case t_void:
		    set_dd(get_dd(v) / 0.0);
		    break;
		case t_int:
		    set_dd(get_dd(v) / get_i(w));
		    break;
		case t_float:
		    set_dd(get_dd(v) / get_d(w));
		    break;
		case t_mpz:
		    set_dd(get_dd(v) / mpz_get_d(get_z(w)));
		    break;
		case t_mpq:
		    set_dd(get_dd(v) / mpq_get_d(get_q(w)));
		    break;
		case t_mpr:
		    ecc_div_dd_r(thr_c, get_dd(v), get_r(w));
		    set_cc(thr_c);
		    break;
		case t_cdd:
		    set_dd(get_dd(v) / get_dd(w));
		    break;
		case t_cqq:
		    set_dd(edd_div_dd_qq(get_dd(v), get_qq(w)));
		    break;
		case t_mpc:
		    ecc_div_dd_cc(thr_c, get_dd(v), get_cc(w));
		    set_cc(thr_c);
		    break;
		default:
		    eraise_exception(except_not_a_number);
	    }
	    break;
	case t_cqq:
	    switch (eobject_type(*w)) {
		case t_void:
		    eraise_exception(except_floating_point_error);
		case t_int:
		    eqq_div_qq_i(thr_qq, get_qq(v), get_i(w));
		    set_qq(thr_qq);
		    break;
		case t_float:
		    set_dd(edd_div_qq_d(get_qq(v), get_d(w)));
		    break;
		case t_mpz:
		    eqq_div_qq_z(thr_qq, get_qq(v), get_z(w));
		    set_qq(thr_qq);
		    break;
		case t_mpq:
		    eqq_div_qq_q(thr_qq, get_qq(v), get_q(w));
		    set_qq(thr_qq);
		    break;
		case t_mpr:
		    ecc_div_qq_r(thr_c, get_qq(v), get_r(w));
		    set_cc(thr_c);
		    break;
		case t_cdd:
		    set_dd(edd_div_qq_dd(get_qq(v), get_dd(w)));
		    break;
		case t_cqq:
		    eqq_div_qq_qq(thr_qq, get_qq(v), get_qq(w));
		    set_qq(thr_qq);
		    break;
		case t_mpc:
		    ecc_div_qq_cc(thr_c, get_qq(v), get_cc(w));
		    set_cc(thr_c);
		    break;
		default:
		    eraise_exception(except_not_a_number);
	    }
	    break;
	case t_mpc:
	    switch (eobject_type(*w)) {
		case t_void:
		    ecc_div_cc_i(thr_c, get_cc(v), 0);
		    set_cc(thr_c);
		    break;
		case t_int:
		    ecc_div_cc_i(thr_c, get_cc(v), get_i(w));
		    set_cc(thr_c);
		    break;
		case t_float:
		    ecc_div_cc_d(thr_c, get_cc(v), get_d(w));
		    set_cc(thr_c);
		    break;
		case t_mpz:
		    ecc_div_cc_z(thr_c, get_cc(v), get_z(w));
		    set_cc(thr_c);
		    break;
		case t_mpq:
		    ecc_div_cc_q(thr_c, get_cc(v), get_q(w));
		    set_cc(thr_c);
		    break;
		case t_mpr:
		    ecc_div_cc_r(thr_c, get_cc(v), get_r(w));
		    set_cc(thr_c);
		    break;
		case t_cdd:
		    ecc_div_cc_dd(thr_c, get_cc(v), get_dd(w));
		    set_cc(thr_c);
		    break;
		case t_cqq:
		    ecc_div_cc_qq(thr_c, get_cc(v), get_qq(w));
		    set_cc(thr_c);
		    break;
		case t_mpc:
		    ecc_div_cc_cc(thr_c, get_cc(v), get_cc(w));
		    set_cc(thr_c);
		    break;
		default:
		    eraise_exception(except_not_a_number);
 	    }
	    break;
	default:
	    eraise_exception(except_not_a_number);
     }
}
#endif
